/****************************************************************************
 * $ Id : ast_event.cpp       2011/07/29
 *
 *        swhors@naver.com
 ****************************************************************************/

/****************************************************************************
 * $ Id  histoty
 *  2011/07/01  : init
 ****************************************************************************/

#include "config.h"

#include <stdio.h>
#include <iostream>

#include <vector>
#include <algorithm>
#include <sys/stat.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <string.h>

#include <unistd.h>

#include <pwd.h>
#include <grp.h>

using namespace std;

#include "constant.h"
#include "skylistener.h"
#include "CmdBase.h"
#include "CmdDtmf.h"
#include "CmdState.h"
#include "CmdJoin.h"
#include "CmdLeave.h"
#include "ast_db.h"
#include "ast_ami.h"
#include "ast_main.h"
#include "ast_event.h"
#include "SkyConfUtil.h"
#include "ast_util.h"

extern char  gOutgoingFolder[256];
extern int   gRunProcess;
extern int   gConnected;
extern int   gIsConnected2DB;
extern char  gRecordPathName[MAX_PATH_LENGTH];

/*
 * ast_login : login to asterisk
 *
 * arg       : aUserName -> User Name
 *             aUserPwd  -> User Password
 *
 * return    : success(1), faile(0)
 */
int ast_login( char * aUserName, char * aUserPwd )
{
    return sendCommand( (char*)"Action: Login\r\n"\
            "Username: %s\r\n"\
            "Secret: %s\r\n\r\n",
            aUserName,
            aUserPwd );
}

/*
 * start_recording : start recodring
 *
 * arg             : confname -> conference number 
 *
 * return          : success(1), faile(0)
 */
int start_recording(char *confname)
{
    int    sRetCode      = 1;
    time_t t             = 0;
    FILE   *fp           = NULL;
    struct passwd *pwd   = NULL;
    struct group  *grp   = NULL;
    char   filename[256] = {0,};
    int    sRet          = 0;

    time(&t);

    snprintf(filename, 256,
        "%s/%s",
        gRecordPathName,
        confname);

    mkdir(filename, 022);

    pwd = getpwnam("asterisk");
    grp = getgrnam("asterisk");

    sRet = lchown( filename, pwd->pw_uid, grp->gr_gid );

    if( sRet != 0 )
    {
        log_message( (char*)"%s",
                "ERR :start_recording, fail to lchown.");
        goto err_start_recording;
    }
    else
    {
        /* do nothing */
    }

    snprintf( filename,
        256,
        "%s/%s/%ld.wav",
        gRecordPathName,
        confname,
        t );

    fp = fopen( filename, "bw" );

    if( fp )
    {
        fclose( fp );
        sRetCode = sendCommand( (char*)"Action: Originate\r\n"\
                "Channel: Local/recorder\\conference\r\n"\
                "MaxRetries: 0\r\n"\
                "RetryTime: 15\r\n"\
                "WaitTime: 15\r\n"\
                "Context: conference\r\n"\
                "Exten: enterconf\r\n"\
                "Priority: 1\r\n"\
                "Callerid: Recorder <100>\r\n"\
                "Variable: conference=%s\r\n"\
                "Variable: RECORDINGFILE=%s\r\n\r\n",
                confname,
                filename );
    }
    else
    {
        /* do nothing */
        log_message( (char*)"%s",
                "ERR :start_recording, cann't open file.");
        goto err_start_recording;
    }

    return sRetCode;

    err_start_recording:
    return 0;
}

void say_number( int number,
    char files[][256],
    int *iCount )
{
    int num   = number;
    int playh = 0;
    int count = 0;
    *iCount   = 0;

    while ( num > 0 || playh > 0 )
    {
        if( num < 0 )
        {
            sprintf( files[count++], "%s", "digits/minus");
            if( num > -32767 )
            {
                num = -num;
            }
            else
            {
                num = 0;
            }
        }
        else
        {
            if( playh > 0 )
            {
                sprintf( files[count++], "%s", "digits/hundred");
                playh = 0;
            }
            else
            {
                if( num < 20 )
                {
                    sprintf( files[count++], "digits/%d", num);
                    num = 0;
                }
                else
                {
                    if( num < 100 )
                    {
                        int math = num /10;
                        math = math *10;
                        sprintf( files[count++], "digits/%d", math);
                        num = num % 10;
                    }
                    else
                    {
                        if( num < 1000 )
                        {
                            int math = num/100;
                            sprintf( files[count++], "digits/%d", math);
                            playh++;
                            num = num % 100;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
        }
    }
    *iCount = count;
}

void getCountFiles(int count, char files[][256], int *iCount)
{
    if( count == 1)
    {
        /* do nothing */

        sprintf(files[0],"conf-onlyperson");
        *iCount = 1;
    }
    else
    {
        if( count == 2)
        {
            sprintf(files[0],"conf-onlyone");
            *iCount = 1;
        }
        else
        {
            if( count > 0 )
            {
                count = count -1;
                say_number(count,files, iCount);
            }
            else
            {
                *iCount =0;
            }
        }
    }
}

void playcount( int count, char *channel)
{
    char files[10][256];
    int  fileCount=10;

    getCountFiles(count, files,&fileCount);

    if( fileCount > 0 )
    {
        char sLine[1024];
        int i=1;
        sprintf( sLine,
            "Command: conference play sound %s %s",
            channel,
            files[0]);

        while ( fileCount > i )
        {
            strcat(sLine, " ");
            strcat(sLine, files[i++]);
        }
        strcat( sLine, " mute\r\n\r\n" );

        sendCommand( (char*)"Action: Command\r\n"\
            "Command: conference stop sounds %s\r\n\r\n"\
            "Action: Command\r\n"\
            "%s",
            channel,
            sLine );
    }
    else
    {
        /* do nothing */
    }
}

void * msg_process(void * aArg)
{

    RECVMSG *sRcvBuf = (RECVMSG *)aArg;

    if( gRunProcess )
    {
        ast_ami astami;
        char *sEnddata = NULL;
        if( astami.parse( sRcvBuf->mMsg, &sEnddata ) != NULL )
        {
            switch ( astami.getCmdType() )
            {
                case cmd_type_event:
                    astami.pData->event();
                    goto suc_msg_process;
                case cmd_type_response:
                case cmd_type_unknown:
                default:
                    goto err_msg_process;
            }
        }
        else
        {
            goto err_msg_process;
        }
    }
    err_msg_process:
    log_message( (char*)"%s",
            (char*)("ERR : msg_process, invalid argument ptr\n"));
suc_msg_process:
    if( sRcvBuf )
    {
        delete sRcvBuf;
        sRcvBuf = NULL;
    }
    return NULL;
}

/////////////////////////////////////////////////////////////
